package com.pangyangyang.elasticsearch.plugin.river;

import com.pangyangyang.elasticsearch.plugin.collector.EventCollector;
import com.pangyangyang.elasticsearch.plugin.exception.MessageRiverException;
import com.pangyangyang.elasticsearch.plugin.handler.EventHandler;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.ESLoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * Created by yangwang on 2015/1/14.
 */
public class Build {

    private String version;
    private String description;
    private Map<String, Class< EventHandler>> handlerClasses;
    private Map<String, Class< EventCollector>> collectorClasses;

    public static  String LOGGER_NAME = "river.messageRiver";
    private static Build instance;
    public final static ESLogger logger = ESLoggerFactory.getLogger(LOGGER_NAME);

    public String getVersion(){
        return version;
    }

    public String getDescription() {
        return description;
    }

    public Map<String, Class<EventHandler>> getHandlerClasses() {
        return handlerClasses;
    }

    public Map<String, Class< EventCollector>> getCollectorClasses() {
        return collectorClasses;
    }

    public static Build getInstance(){
        if(instance == null){
            try{
                InputStream res = Build.class.getClassLoader().getResourceAsStream("message-build.properties");
                Properties properties = new Properties();
                properties.load(res);

                instance = new Build();
                instance.version = properties.getProperty("version");
                instance.description = properties.getProperty("description");
                String handlerClasses = properties.getProperty("handler.classes");
                String collectorClasses = properties.getProperty("collector.classes");

                logger.debug("properties config loaded.");
                for(Map.Entry entry : properties.entrySet()){
                    logger.debug("property {} : {}", entry.getKey(), entry.getValue());
                }

                instance.handlerClasses = toMap(handlerClasses);
                instance.collectorClasses = toMap(collectorClasses);
            } catch (IOException ioe){
                logger.error("Message plugin load properties failed.", ioe);
                throw new MessageRiverException("Message plugin load properties failed.", ioe);
            }
        }
        return instance;
    }

    private static <T> Map<String, Class<T>> toMap(String value){
        String handlerClassName = null;
        Map<String, Class<T>> classes = new HashMap<>();
        try{
            String[] handlerClasses = value.split(";");
            for(int i  =0; i< handlerClasses.length;  i++){
                handlerClassName = handlerClasses[i];
                String bindingName = handlerClassName.split(":")[0];
                Class<T> clazz = (Class<T>) Class.forName(handlerClassName.split(":")[1]);
                classes.put( bindingName, clazz);
            }
        } catch (ClassNotFoundException e){
            logger.error("class load failed.", e);
            throw new MessageRiverException(String.format("class load failed %s.", handlerClassName), e);
        }

        return classes;
    }
}
